/*
 * <b>文件名</b>：LoginServiceImpl.java
 *
 * 文件描述：
 *
 *
 * 2017年11月16日  下午4:17:46
 */

package com.bink.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.bink.constant.ShiroConstant;
import com.bink.core.base.BaseResponse;
import com.bink.core.base.ShiroUser;
import com.bink.core.base.SimpleToken;
import com.bink.core.bridge.UserBridgeService;
import com.bink.core.impl.JwtTokenManager;
import com.bink.service.LoginService;
import com.bink.utils.ShiroUserUtil;
import com.bink.utils.ShiroUtil;
import com.bink.vo.LoginVo;
import lombok.extern.log4j.Log4j2;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.subject.Subject;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * @Description: 登陆业务实现
 */
@Service("loginService")
@Log4j2
public class LoginServiceImpl implements LoginService {

    @Autowired
    UserBridgeService userBridgeService;

    @Autowired
    JwtTokenManager jwtTokenManager;

    @Override
    public Map<String, String> route(LoginVo loginVo) throws UnknownAccountException, IncorrectCredentialsException {
        Map<String, String> map = new HashMap<>();
        try {
            SimpleToken token = new SimpleToken(null, loginVo.getLoginName(), loginVo.getPassWord());
            Subject subject = SecurityUtils.getSubject();
            subject.login(token);
            this.loadAuthorityToCache(token);
        } catch (UnknownAccountException ex) {
            log.error("登陆异常:{ }", ex);
            throw new UnknownAccountException(ex);
        } catch (IncorrectCredentialsException ex) {
            log.error("登陆异常:{ }", ex);
            throw new IncorrectCredentialsException(ex);
        }
        map.put("authorizationKey", ShiroUtil.getShiroSessionId());
        return map;
    }

    /**
     * @Description: jwt方式登录
     * @Param: loginVo 登录参数
     * @Return:
     */
    @Override
    public BaseResponse routeForJwt(LoginVo loginVo) throws UnknownAccountException, IncorrectCredentialsException {
        //实现登录
        String jwtToken = null;
        try {
            SimpleToken simpleToken = new SimpleToken(null, loginVo.getLoginName(), loginVo.getPassWord());
            Subject subject = SecurityUtils.getSubject();
            subject.login(simpleToken);
            //登录完成之后需要颁发令牌
            String sessionId = ShiroUserUtil.getShiroSessionId();
            ShiroUser shiroUser = ShiroUserUtil.getShiroUser();
            Map<String,Object> claims = new HashMap<>();
            claims.put("shiroUser", JSONObject.toJSONString(shiroUser));
            long ttlMillis = subject.getSession().getTimeout();
            jwtToken = jwtTokenManager.issuedToken("system", ttlMillis, sessionId, claims);
            //缓存加载
            this.loadAuthorityToCache(simpleToken);
        }catch (Exception e){
            return new BaseResponse(ShiroConstant.LOGIN_FAILURE_CODE, ShiroConstant.LOGIN_FAILURE_MESSAGE);
        }
        return new BaseResponse(ShiroConstant.LOGIN_SUCCESS_CODE, ShiroConstant.LOGIN_SUCCESS_MESSAGE, jwtToken);
    }

    /**
     * @Description: 加载用户信息进缓存
     * @Param: token
     */
    private void loadAuthorityToCache(SimpleToken token){
        //登陆成功后缓存用户的权限信息进入缓存
        ShiroUser shiroUser = ShiroUserUtil.getShiroUser();
        userBridgeService.loadUserAuthorityToCache(shiroUser);

    }

}
